package com.haidao.admin.component.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.haidao.admin.component.dao.UserOperationDao;
import com.haidao.admin.component.entity.UserOperation;
import com.haidao.admin.component.params.UserOperationParam;
import com.haidao.admin.component.resp.PageResult;
import com.haidao.admin.component.service.UserOperationService;
import com.haidao.admin.component.service.thirdpart.IJiDaService;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


@Service
@RequiredArgsConstructor
@Slf4j
public class UserOperationServiceImpl implements UserOperationService {

    private final UserOperationDao userOperationDao;
    private final IJiDaService jiDaService;

    /**
     * 126.207
     * @param userOperation
     */
    @Override
    public void save(UserOperation userOperation) {
        userOperation.setEventId(IdUtil.getSnowflakeNextId());
        // 整体签名
        String hmac = jiDaService.signature(userOperation.allFields());
        // 对用户名和操作内容进行加密
        String enUsername = jiDaService.encrypt(userOperation.getUsername());
        String enContent = jiDaService.encrypt(userOperation.getOperationContent());

        userOperation.setUsername(enUsername);
        userOperation.setOperationContent(enContent);
        userOperation.setHmac(hmac);

        userOperationDao.save(userOperation);
    }

    @Override
    public Page<UserOperation> list(UserOperationParam param) {
        PageRequest pageRequest = PageRequest.of(param.getPage()-1, param.getPageSize());

        //构造查询条件
        Specification<UserOperation> specification = new Specification<UserOperation>() {
            @Override
            public Predicate toPredicate(Root<UserOperation> root, //查询的类型（实体类的一个路径,告诉查询用的是哪个字段），使用get获取字段
                                         CriteriaQuery<?> query, //查询的条件
                                         CriteriaBuilder criteriaBuilder) { //构造条件
                //创建条件集合
                List<Predicate> predicates = new ArrayList<>();
                //判断传入参数是否为空，不为空就添加至查询条件中
                if(StrUtil.isNotBlank(param.getUsername())){
                    //equal表示传入字段需要等于数据库字段（这里可以改成like变为模糊查询）
                    predicates.add(criteriaBuilder.equal(root.get("username"), jiDaService.encrypt(param.getUsername())));
                }

                if((param.getBeginTime() != null) && (param.getEndTime() != null)){
                    predicates.add(criteriaBuilder.between(root.get("operation_time"), param.getBeginTime(), param.getEndTime()));
                }
                //创建一个条件的集合，长度为上面满足条件的个数（目的是将predicates列表转为集合）
                Predicate[] pre = new Predicate[predicates.size()];
                return query.where(predicates.toArray(pre)).getRestriction();
            }
        };

        Page<UserOperation> pageResult = userOperationDao.findAll(specification, pageRequest);
        pageResult.forEach(e -> {
            String username = jiDaService.decrypt(e.getUsername());
            String content = jiDaService.decrypt(e.getOperationContent());
            e.setUsername(username);
            e.setOperationContent(content);
            boolean verify = jiDaService.verify(e.allFields(), e.getHmac());
            e.setChanged(!verify);

        });
        return pageResult;
    }


}
